# -*- coding: utf-8 -*-
#===============================================================================
# Koro Business Environment
# Copyright (C) 2008  Antonio Corroppoli
#
#This file is part of Koro BE.
# 
# Koro BE is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# Koro BE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Koro BE; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#===============================================================================

'''
Created on 19/ago/2011

@author: antstud
'''
from decimal import Decimal
from datetime import date
from sqlalchemy.orm import object_session,reconstructor
from koro import util
from koro.core import exception
from koro.core.model import IDObject

#===============================================================================
# Contatore
#===============================================================================
class Contatore(object):
    def __init__(self):
        self.valore=0
        self.serie=''
        self.tipo_documento=None
    
    def next(self):
        return self.valore+1 
    
    def validate(self):
        assert self.tipo_documento is not None,exception.KoroInvalidObject('Specificare il tipo documento')       
        

#===============================================================================
# DocumentoBase
#===============================================================================
class DocumentoBase(IDObject):
    '''Questa classe deve essere estesa dalle classi documento.
    Contiene i metodi comuni a tutti i documenti'''
    def __init__(self):
        IDObject.__init__(self)
        self.numero=None
        self.serie=''
        self.data=date.today()
        self.tipo_documento=None
        self.intestatario=None
        self.fk_intestatario=None
        self.commento_interno=''
        self.dettaglio=DettaglioDocumento()
        #documento generato
        self.fk_documento_generato=None
        self.documento_generato=None
        self.chiuso=False
        #spese e totali
        self.totale=Decimal('0.00')
        self.totale_imponibile=Decimal('0.00')
        self.totale_iva=Decimal('0.00')
        self.spese_descr=''
        self.spese_iva_perc=Decimal('20.00')
        self.spese_fk_iva=None
        self.spese_importo=Decimal('0.00')
    
    @reconstructor
    def on_load(self):
        self.data=util.to_date(self.data)
        #self.totale=util.to_decimal(self.totale)
        self.totale_imponibile=util.to_decimal(self.totale_imponibile)
        self.totale_iva=util.to_decimal(self.totale_iva)
        #self.spese_iva_perc=util.to_decimal(self.spese_iva_perc)
        self.spese_importo=util.to_decimal(self.spese_importo)
        
    def get_intestatario_fmt(self):
        '''Restituisce la ragione sociale dell'intestatario documento.'''
        if self.intestatario is None:
            return ''
        return self.intestatario.ragione_sociale
    
    def get_ID_intestatario_fmt(self):
        '''Restituisce l'ID dell'intestatario documento.'''
        if self.intestatario is None:
            return ''
        return self.intestatario.get_ID_fmt()
    
    def get_data_documento(self):
        if self.data is None:
            self.data=date.today()
        return util.to_date(self.data)
    
#    def get_format_data(self):
#        '''Questo metodo dovrebbe essere eliminato. Usa get_data_documento_fmt.'''
#        if isinstance(self.data,date):
#            return util.format_date(self.data)
#        return self.data
    
    def get_data_documento_fmt(self):
        return util.format_date(self.get_data_documento())
    
    def get_iva_spese(self):
        if self.iva_spese is None:
            return Decimal('0.00')
        return self.iva_spese.aliquota
    
    def get_totale_spese(self):
        return util.round(self.spese_importo+(self.spese_importo/100*self.get_iva_spese()))
    
    def get_totale_spese_fmt(self):
        return util.euro(self.get_totale_spese())
    
    def get_iva_intestatario(self):#TODO:controllare
        if self.intestatario is None or self.intestatario.iva is None:
            return None
        return self.intestatario.iva
    
    def get_sconti(self):#TODO:
        return ''
    
    def get_tipo_documento_fmt(self,breve=False):
        if breve:
            return TipoDocumento.descrizione_breve(self.tipo_documento)
        return TipoDocumento.descrizione(self.tipo_documento)        
    
    def get_totale(self):
        return self.totale_imponibile+self.totale_iva
    
    def get_totale_fmt(self):
        return util.euro(self.get_totale())
    
    def get_totale_imponibile(self):
        return self.totale_imponibile
    
    def get_totale_imponibile_fmt(self):
        return util.euro(self.totale_imponibile)
    
    def get_totale_iva(self):
        return self.totale_iva
    
    def get_totale_iva_fmt(self):
        return util.euro(self.totale_iva)
    
    def set_data_documento(self, value):
        self.data = value
    
    def set_totale(self, value):
        self.totale = value
    
    def set_totale_imponibile(self, value):
        self.totale_imponibile = value
    
    def set_totale_iva(self, value):
        self.totale_iva = value
        
    def set_importo_spese(self,importo):
        if importo=='':
            importo='0'
        self.spese_importo=Decimal(importo)
    
    def set_iva_spese(self,iva):
        self.iva_spese=iva
        self.spese_fk_iva=iva.codice
    
    def set_intestatario(self,value):
        self.intestatario=value
        if value is not None:
            self.fk_intestatario=value.ID
        else:
            self.fk_intestatario=None
    
    def set_listino(self,listino):
        if listino is not None:
            self.fk_listino=listino.ID
        else:
            self.fk_listino=None
        self.listino=listino
    
    def calcola_totali(self):
        tot_imp=0
        tot_iva=0
        for riga in self.dettaglio:
            tot_imp+=riga.get_totale()
            tot_iva+=riga.get_iva_riga()
        self.totale_imponibile=tot_imp+self.spese_importo
        iva_spese=util.round(self.spese_importo/100*self.get_iva_spese())
        self.totale_iva=tot_iva+iva_spese
    
    def save_riga(self,*args,**kwargs):
        self.dettaglio.save_riga(*args,**kwargs)
    
    def get_documento_generato(self):
        session=object_session(self)
        if session is None:
            raise exception.KoroInternalError("L'istanza non è legata a nessuna sessione" )
        if self.fk_documento_generato is None:
            return None
        query=session.query(self.__class__).from_statement('SELECT * from documenti where ID={0}'.format(self.fk_documento_generato))
        self.documento_generato=query.first()        
        return self.documento_generato
    
    def chiudi(self,doc_generato):
        self.fk_documento_generato=doc_generato.ID
        self.documento_generato=doc_generato
        self.chiuso=True
        

#===============================================================================
# Documento
#===============================================================================
class Documento(DocumentoBase):
#    FATTURA=1
#    FATTURA_ACC=2
#    DDT=3
#    PREVENTIVO=4
#    ARRIVO_MERCE=10
#    REG_FATT_FORN=20
    
    @staticmethod
    def get_new_dettaglio():
        return DettaglioDocumento()
            
    def __init__(self):
        DocumentoBase.__init__(self)
    
    def validate(self):
        return
        
    def is_fattura(self):
        return self.tipo_documento==TipoDocumento.FATTURA
    
    def is_ddt(self):
        return self.tipo_documento==TipoDocumento.DDT
    
    def is_fattura_acc(self):
        return self.tipo_documento==TipoDocumento.FATTURA_ACC
    
    def is_arrivo(self):
        return self.tipo_documento==TipoDocumento.ARRIVO_MERCE
    
    def is_preventivo(self):
        return self.tipo_documento==TipoDocumento.PREVENTIVO
    
    def is_reg_fatt_forn(self):
        return self.tipo_documento==TipoDocumento.REG_FATT_FORN
    
    def is_chiuso(self):
        return self.chiuso
    
    def get_documento_generato_fmt(self):
        raise Exception('Override in subclass')    
   
    def get_numero_documento(self):
        return self.numero
    
    def get_numero_documento_fmt(self):
        return str(self.numero)
    
    def get_pagamento_fmt(self):
        return ''

    def get_tipo_documento(self):
        return self.tipo_documento#.descrizione
    
#    def get_tipo_documento_fmt(self):
#        return TipoDocumento.descrizione(self.tipo_documento)
    
    def remove_riga(self,riga):
        '''Rimuove una riga dal dettaglio.'''
        try:
            self.dettaglio.remove(riga)
        except ValueError:
            print 'riga numero {0} non trovata'.format(riga.numero)
    
    def save_riga(self,*args,**kwargs):
        self.dettaglio.save_riga(*args,**kwargs)
        prodotto=kwargs.pop('prodotto',None)
        if prodotto is None or \
        self.intestatario is None or \
        not self.intestatario.is_fornitore():
            return
        if not prodotto.has_fornitore(self.intestatario):
            msg='{0} non è un fornitore del prodotto.'.format(self.intestatario.ragione_sociale)
            raise exception.KoroIncompleteObject(msg,prodotto,self.intestatario)   
        
    
#    def get_fk_tipo_documento(self):
#        return self.fk_tipo_documento
    
    def set_numero(self, value):
        self.numero = value

    def set_tipo_documento(self,value):
        self.tipo_documento=value#valutare se fare il check su value        
    
    def is_editable(self):#TODO:sviluppare
        #return self.ID is None
        return True
    
    def get_riepilogo_aliquote(self):
        aliquote={}
        for riga in self.dettaglio:
            iva = riga.get_codice_iva_riga()
            imponibile = riga.get_totale()
            if iva not in aliquote:
                aliquote[iva] = [Decimal('0.00'),riga.iva_obj]
            aliquote[iva][0] += imponibile
        return aliquote
    

#===============================================================================
# RegFattForn Registrazione fattura Fornitore
#===============================================================================
class RegFattForn(Documento):
    def __init__(self):
        Documento.__init__(self)
        self.tipo_documento=TipoDocumento.REG_FATT_FORN
        self.data_fatt_forn=date.today()
        self.num_fatt_forn=None
    
    @reconstructor
    def on_load(self):
        self.data_fatt_forn=util.to_date(self.data_fatt_forn)
    
    def validate(self):
        if not util.to_bool(self.num_fatt_forn):
            raise exception.KoroInvalidObject('Il numero Fattura fornitore è richiesto')
        if not util.to_bool(self.intestatario):
            raise exception.KoroInvalidObject('Indicare il fornitore')
        if not util.to_bool(self.data_fatt_forn):
            raise exception.KoroInvalidObject('Indicare la data della fattura fornitore')
        Documento.validate(self)
    
    def set_numero_fatt_forn(self,num):
        self.num_fatt_forn=num
    
    def get_data_fatt_forn(self):
        if self.data_fatt_forn is None:
            return date.today()
        return util.to_date(self.data_fatt_forn)
    
    def get_data_fatt_forn_fmt(self):
        return util.format_date(self.get_data_fatt_forn())
    
    def get_numero_fatt_forn_fmt(self):
        if self.num_fatt_forn is None:
            return ''
        return str(self.num_fatt_forn)


#===============================================================================
# ArrivoMerce
#===============================================================================
class ArrivoMerce(Documento):
    def __init__(self):
        Documento.__init__(self)
        self.tipo_documento=TipoDocumento.ARRIVO_MERCE
    
    def validate(self):        
        if not util.to_bool(self.intestatario):
            raise exception.KoroInvalidObject('Indicare il fornitore')        
        Documento.validate(self)
    
    def get_documento_generato_fmt(self):
        if self.get_documento_generato() is None:
            return u''
        template=u'{0} {1} del {2}'
        return template.format(TipoDocumento.descrizione_breve(self.documento_generato.tipo_documento),
                               self.documento_generato.num_fatt_forn,
                               self.documento_generato.get_data_fatt_forn_fmt())#questo è solo per gli arrivi!
    
    def get_dettaglio_reg_fatt_forn(self):
        righe=self.get_riepilogo_aliquote()
        descrizione='{0} numero {1} del {2}'.format(self.get_tipo_documento_fmt(),
                                                    self.numero,
                                                    self.get_data_documento_fmt())
        dettaglio=DettaglioDocumento()
        for k in righe:
            dettaglio.save_riga(numero=-1,
                                descrizione=descrizione,
                                prezzo=righe[k][0],
                                iva=righe[k][1],
                                sconti='')
        if not self.spese_importo.is_zero():
            dettaglio.save_riga(numero=-1,
                                descrizione=self.spese_descr,
                                prezzo=self.spese_importo,
                                iva=self.iva_spese,
                                sconti='')
        return dettaglio


#===============================================================================
# Preventivo
#===============================================================================
class Preventivo(Documento):
    def __init__(self):
        Documento.__init__(self)
        self.tipo_documento=TipoDocumento.PREVENTIVO


class Fattura(Documento):
    def __init__(self):
        Documento.__init__(self)
        self.tipo_documento=TipoDocumento.FATTURA
    
    def validate(self):        
        if not util.to_bool(self.intestatario):
            raise exception.KoroInvalidObject('Indicare il cliente')        
        Documento.validate(self)


class VenditaBanco(Documento):
    def __init__(self):
        Documento.__init__(self)
        self.tipo_documento=TipoDocumento.VENDITA_BANCO


class RapportoIntervento(Documento):
    def __init__(self):
        Documento.__init__(self)
        self.tipo_documento=TipoDocumento.RAPPORTO_INTERVENTO


class DDT(Documento):
    def __init__(self):
        Documento.__init__(self)
        self.tipo_documento=TipoDocumento.DDT
        self.destinazione=False
        self.causale=None
        self.data_traporto=None
        self.porto=None
        self._incaricato_trasporto=None
        self.numero_colli=None
        self.peso=None
        self.aspetto_beni=None
    
    @reconstructor
    def on_load(self):
        self.data_traporto=util.to_date(self.data_traporto)
    


#===============================================================================
# Dettaglio è una lista di oggetto Riga
#===============================================================================
class DettaglioDocumento(list):
    def __init__(self):
        super(DettaglioDocumento,self).__init__()
        self.cont=0
    
    def _get_nuova_riga(self):
        return RigaDocumento()
    
    def clona(self):
        nuovo_dettaglio=DettaglioDocumento()
        for item in self:
            nuovo_dettaglio.save_riga(numero=item.numero,
                                      prodotto=item.prodotto,
                                      prezzo=item.prezzo,
                                      quantita=item.quantita,
                                      iva=item.iva_obj,
                                      sconti=item.sconti,
                                      descrizione=item.descrizione_riga)
        return nuovo_dettaglio
                     
    def _next_num(self):
        if len(self)==0:
            self.cont=0
        return self.cont+1
    
    def append(self,riga):        
        if riga.numero>self.cont:
            self.cont=riga.numero
        super(DettaglioDocumento,self).append(riga)
    
    def save_riga(self,**kwargs):
        '''Aggiunge o aggiorna una riga documento. Accetta l'iva come oggetto'''
        numero=kwargs.pop('numero','')
        prodotto=kwargs.pop('prodotto',None)
        cod_prod_forn=kwargs.pop('cod_prod_forn','')
        descrizione=kwargs.pop('descrizione','')
        prezzo=Decimal(kwargs['prezzo'])
        quantita=int(kwargs.pop('quantita',-1))
        iva=kwargs['iva']
        sconti=kwargs.pop('sconti','')
        movimenta=kwargs.pop('movimenta',False)           
        
        riga=self.find_riga(numero)
        if riga is None:
            riga=self._get_nuova_riga()
            riga.numero=self._next_num()
            self.append(riga)##TODO: controllare se funziona!
        riga.set(numero=riga.numero,
                 prodotto=prodotto,
                 cod_prod_forn=cod_prod_forn,
                 prezzo=prezzo,
                 quantita=quantita,
                 iva=iva,
                 sconti=sconti,
                 descrizione=descrizione,
                 movimenta=movimenta)
        #riga.perc_iva=iva.aliquota
        #riga.codice_iva=iva.codice
        
    def add_riga_(self,*args,**kwargs):
        '''Aggiunge una nuova riga documento. A differenza di save_riga, che accetta l'iva come oggetto,
        prende i parametri iva_riga e codice_iva.Adatto se si conosce gia' l'importo iva della riga.'''
        prodotto=kwargs['prodotto']
        prezzo=Decimal(kwargs['prezzo'])
        quantita=int(kwargs['quantita'])
        iva_riga=kwargs['iva_riga']
        codice_iva=kwargs['codice_iva']
        sconti=kwargs.pop('sconti','')                
    
        riga=self._get_nuova_riga()
        riga.set_numero(self._next_num())
        riga.set_prodotto(prodotto)
        riga.set_prezzo(prezzo)
        riga.set_quantita(quantita)
        riga.set_iva_riga(iva_riga)
        riga.set_codice_iva(codice_iva)
        riga.set_sconti(sconti)
        #riga.perc_iva=iva.aliquota
        #riga.codice_iva=iva.codice
        self.append(riga)
    
    def _update_riga_(self,*args,**kwargs):#mai usato
        '''Aggiorna una riga esistente con i nuovi valori.'''
        numero=int(kwargs['numero'])
        prodotto=kwargs['prodotto']
        prezzo=Decimal(kwargs['prezzo'])
        quantita=int(kwargs['quantita'])
        iva=kwargs['iva']
        sconti=kwargs.pop('sconti','')
        
        #iva_riga=util.round((prezzo*iva.aliquota/100)*quantita)        
    
        riga=self.find_riga(numero)
        if riga is None:
            raise Exception('Riga {0} non trovata: nessuna riga da aggiornare.'.format(numero))
            return False
        riga.set(numero=riga.numero,prodotto=prodotto,
                 prezzo=prezzo,
                 quantita=quantita,
                 iva=iva,
                 sconti=sconti)
        #riga.perc_iva=iva.aliquota
        #riga.codice_iva=iva.codice
        return True
    
    def find_riga(self,numero):
        if numero=='' or numero==-1:
            return None
        numero=int(numero)
        for item in self:
            if item.numero==numero:
                return item
        return None


#===============================================================================
# Riga
#===============================================================================
class Riga(object):
    def __init__(self):
        self.numero=None
        self.prodotto=None
        self.fk_prodotto=None
        self.cod_prod_forn=None
        self.descrizione_riga=''
        self.prezzo=Decimal('0.00')
        self.quantita=0
        self.iva_riga=Decimal('0.00')
        self.iva_obj=None
        self.fk_iva=u''
        #self.perc_iva=Decimal(0)
        #self.prezzo_fornitore=Decimal(0)
        self.sconti=u''
        self.movimenta=False
    
    @reconstructor
    def on_load(self):
        self.prezzo=util.to_decimal(self.prezzo)
        self.iva_riga=util.to_decimal(self.iva_riga)
    
    def get_ID_prodotto_fmt(self):
        if self.prodotto is None:
            return ''
        return str(self.prodotto.ID)
    
    def get_cod_prod_forn(self):
        return self.cod_prod_forn

#    def get_prodotto_fmt(self):
#        if self.prodotto is None:
#            return self.descrizione_riga
#        return '{0} - {1}'.format(self.prodotto.get_codice_prod_forn(),self.prodotto.descrizione)
    
    def get_descrizione(self):
        return self.descrizione_riga
    
    def set(self,**kw):
        self.set_numero(kw['numero'])
        self.set_prodotto(kw['prodotto'])
        self.set_cod_prod_forn(kw['cod_prod_forn'])
        self.set_descrizione(kw['descrizione'])
        self.set_prezzo(kw['prezzo'])
        self.set_quantita(kw['quantita'])
        self.set_iva(kw['iva'])
        self.set_sconti(kw.pop('sconti',''))
        self.movimenta=kw['movimenta']
    
    def get_totale_riga(self):
        '''Totale con iva'''
        return self.get_iva_riga()+self.get_totale()        
        
    def get_numero(self):
        return str(self.numero)

    def get_prodotto(self):
        '''Restituiscel'oggetto Prodotto o la descrizione della riga se il prodotto non è impostato. '''
        if self.prodotto is None:
            return self.descrizione_riga
        return self.prodotto

    def get_quantita(self):
        return self.quantita
    
    def get_iva_riga(self):
        if self.iva_obj is not None:
            self._aggiorna_iva_riga()
        return self.iva_riga
    
    def get_codice_iva_riga(self):
        return self.iva_obj.codice
    
    def get_iva_riga_fmt(self):
        return util.euro(self.get_iva_riga())
    
    def get_codice_iva(self):
        return self.fk_iva
    
    def get_prezzo(self):
        return self.prezzo
    
    def get_prezzo_fmt(self):
        return util.euro(self.get_prezzo())
    
    def get_totale(self):#imponibile riga
        '''Totale senza iva. Deprecato. usa get_imponibile_riga()'''
        return util.round(self.get_prezzo_scontato()*abs(self.quantita))
    
    def get_imponibile_riga(self):
        return util.round(self.get_prezzo_scontato()*abs(self.quantita))
    
    def get_totale_fmt(self):
        return util.euro(self.get_totale())
    
    def get_iva_perc(self):
        if self.iva_obj is None:
            return Decimal('0.00')
        return self.iva_obj.aliquota
    
    def get_sconti(self):
        if self.sconti is None:
            self.sconti=''
        return self.sconti
    
    def get_prezzo_scontato(self):
        token_list = util.tokenizer_sconti(self.sconti)
        sconto = 0
        prezzo_scontato = self._calcola_prezzo_scontato(self.prezzo, token_list)
        return prezzo_scontato
    
    def _calcola_prezzo_scontato(self, prezzo, token_list):
        if len(token_list) == 0:
            return prezzo
        if token_list[0] == '-':
            prezzo = prezzo + (prezzo / 100 * token_list[1])
            del token_list[0]
            del token_list[0]
        elif token_list[0] == '+':
            prezzo = prezzo - (prezzo / 100 * token_list[1])
            del token_list[0]
            del token_list[0]
        else:
            prezzo = prezzo - (prezzo / 100 * token_list[0])
            del token_list[0]        
        return self._calcola_prezzo_scontato(prezzo, token_list)
    
    def set_sconti(self,value):
        if util.validate_sconti(value):
            self.sconti=value
        #self._calcola_sconto()

    def set_numero(self, value):
        self.numero = int(value)

    def set_prodotto_old(self, value):
        #se riceve una stringa setta la descrizione
        if isinstance(value,basestring):
            self.descrizione_riga=value
            value=None            
        self.prodotto = value
    
    def set_prodotto(self, value):            
        self.prodotto = value
        if self.prodotto is not None:
            self.descrizione_riga=self.prodotto.descrizione
            self.fk_prodotto=self.prodotto.ID
        else:
            self.fk_prodotto=None
            self.descrizione_riga=''
    
    def set_descrizione(self,descrizione):
        self.descrizione_riga=descrizione

    def set_quantita(self, value):
        self.quantita = int(value)
    
    def set_iva(self,value):
        self.fk_iva=value.codice
        self.iva_obj=value
        self._aggiorna_iva_riga()
    
    def set_cod_prod_forn(self,val):
        self.cod_prod_forn=val
    
    def set_iva_riga(self,value):
        self.iva_riga=Decimal(value)
    
    def set_codice_iva(self,codice):
        self.fk_iva=codice
    
#    def set_perc_iva(self,perc_iva):
#        self.perc_iva=Decimal(perc_iva)
    
    def set_prezzo(self,value):
        self.prezzo=Decimal(value)

    def del_prodotto(self):
        del self.prodotto
    
    def da_movimentare(self):
        return self.movimenta
#        if self.prodotto is None:
#            return False
#        return self.prodotto.has_magazzino()
    def movimenta_fmt(self):
        ret=''
        if self.movimenta:
            ret='X'
        return ret
    
    def _aggiorna_iva_riga(self):
        iva_perc=self.get_iva_perc()
        self.iva_riga=util.round((self.prezzo*iva_perc/100)*abs(self.quantita))


#===============================================================================
# RigaDocumento wrapper per la classe Riga
#===============================================================================
class RigaDocumento(Riga):
    def __init__(self):
        super(RigaDocumento,self).__init__()


#===============================================================================
# TipoDocumento
#===============================================================================
#class TipoDocumento(IDObject):
#    TIPO_MAP={Documento.FATTURA:'Fattura',
#              Documento.ARRIVO_MERCE:'Arrivo'}
#    @staticmethod
#    def get_tipo_fmt(tipo_id):
#        return TipoDocumento.TIPO_MAP[tipo_id]
#    
#    def __init__(self):
#        IDObject.__init__(self)
#        self.descrizione=''

class TipoDocumento(object):
    #indici mappa
    _DESCR=0
    _DESCR_BREVE=1
    _CLASSE=2
    #classe documento
    VENDITA=0
    ACQUISTO=1
    MOVIMENTAZIONE=2
    #tipi documento
    DOCBASE=0#esiste solo per polymorphic_identity nel database
    FATTURA=1
    FATTURA_ACC=2
    DDT=3
    PREVENTIVO=4
    VENDITA_BANCO=5
    RAPPORTO_INTERVENTO=6
    ARRIVO_MERCE=10
    REG_FATT_FORN=20
    
    MAP={FATTURA:('Fattura','Fatt.',VENDITA),
         FATTURA_ACC:('Fattura Accompagnatoria','Fatt.Acc.',VENDITA),
         DDT:('Doc. di Trasporto','DDT',MOVIMENTAZIONE),
         PREVENTIVO:('Preventivo','Prev.',VENDITA),
         VENDITA_BANCO:('Vendita al Banco','Banco.',VENDITA),
         ARRIVO_MERCE:('Arrivo Merce','Arrivo',ACQUISTO),
         REG_FATT_FORN:('Reg. Fatture Forn.','Fattura Forn.',ACQUISTO),
         }
    
    @staticmethod
    def descrizione(key):
        return TipoDocumento.MAP[key][TipoDocumento._DESCR]
    
    @staticmethod
    def descrizione_breve(key):
        return TipoDocumento.MAP[key][TipoDocumento._DESCR_BREVE]
    
    @staticmethod
    def classe(key):
        return TipoDocumento.MAP[key][TipoDocumento._CLASSE]

